package com.eudon.genius.api.core.parser.component;

import com.eudon.genius.api.core.dto.ApiInfo;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.resolution.types.ResolvedType;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

/**
 * 方法参数解析器
 * 负责解析方法参数的详细信息，包括参数名、类型、注解等
 *
 * @author eudon
 * @since 2025/9/25
 */
@Slf4j
public class ParameterParser {

    private final TypeResolver typeResolver;
    private final AnnotationParser annotationParser;

    public ParameterParser(TypeResolver typeResolver) {
        this.typeResolver = typeResolver;
        this.annotationParser = new AnnotationParser();
    }

    /**
     * 解析方法的所有参数
     *
     * @param methodDeclaration 方法声明
     * @param methodDocInfo     方法文档信息
     * @return 参数信息列表
     */
    public List<ApiInfo.Parameter> parseMethodParameters(
            MethodDeclaration methodDeclaration,
            JavaDocParser.MethodDocInfo methodDocInfo) {

        List<ApiInfo.Parameter> parameters = new ArrayList<>();

        for (Parameter parameter : methodDeclaration.getParameters()) {
            try {
                ApiInfo.Parameter paramInfo = parseParameter(parameter, methodDocInfo);
                if (paramInfo != null) {
                    parameters.add(paramInfo);
                }
            } catch (Exception e) {
                log.warn("解析参数失败: {}, 错误: {}", parameter.getNameAsString(), e.getMessage());
            }
        }

        return parameters;
    }

    /**
     * 解析单个参数
     *
     * @param parameter     参数
     * @param methodDocInfo 方法文档信息
     * @return 参数信息
     */
    public ApiInfo.Parameter parseParameter(Parameter parameter, JavaDocParser.MethodDocInfo methodDocInfo) {
        ApiInfo.Parameter paramInfo = new ApiInfo.Parameter();

        // 设置参数名称
        String paramName = parameter.getNameAsString();
        paramInfo.setParameterName(paramName);

        // 设置参数描述
        String paramDesc = methodDocInfo.getParameterDescriptions().getOrDefault(paramName, "");
        paramInfo.setParameterDesc(paramDesc.isEmpty() ? paramName : paramDesc);

        // 解析参数类型
        parseParameterType(parameter, paramInfo);

        // 解析参数注解
        parseParameterAnnotations(parameter, paramInfo);

        // 解析复杂类型的字段
        if (!Boolean.TRUE.equals(paramInfo.getIsPrimitive()) && paramInfo.getLocation() == ApiInfo.ParameterLocation.BODY) {
            try {
                List<ApiInfo.Parameter> fields = typeResolver.resolveTypeFields(parameter.getType());
                paramInfo.setFields(fields);
            } catch (Exception e) {
                log.warn("解析参数 {} 的字段失败: {}", paramName, e.getMessage());
            }
        }

        return paramInfo;
    }

    /**
     * 解析参数类型信息
     */
    private void parseParameterType(Parameter parameter, ApiInfo.Parameter paramInfo) {
        Type paramType = parameter.getType();

        // 设置类型名称
        String typeName = paramType.asString();
        paramInfo.setParameterType(typeName);
        paramInfo.setSimpleTypeName(getSimpleTypeName(typeName));

        // 判断是否为基本类型
        boolean isPrimitive = typeResolver.isPrimitiveType(typeName);
        paramInfo.setIsPrimitive(isPrimitive);

        // 尝试解析完整类型信息
        try {
            ResolvedType resolvedType = paramType.resolve();
            String qualifiedName = resolvedType.describe();
            paramInfo.setParameterType(qualifiedName);

            // 重新判断是否为基本类型
            isPrimitive = typeResolver.isPrimitiveType(qualifiedName);
            paramInfo.setIsPrimitive(isPrimitive);

        } catch (Exception e) {
            log.debug("无法解析参数类型: {}, 使用原始类型名称", typeName);
        }
    }

    /**
     * 解析参数注解信息
     */
    private void parseParameterAnnotations(Parameter parameter, ApiInfo.Parameter paramInfo) {
        AnnotationParser.ParameterAnnotationInfo annotationInfo =
                annotationParser.parseParameterAnnotations(parameter);

        // 设置参数位置
        paramInfo.setLocation(annotationInfo.getLocation());

        // 设置是否可空
        paramInfo.setNullable(annotationInfo.isNullable());

        // 设置默认值
        if (annotationInfo.getDefaultValue() != null && !annotationInfo.getDefaultValue().isEmpty()) {
            paramInfo.setDefaultValue(annotationInfo.getDefaultValue());
        }

        // 如果注解中指定了参数名，使用注解中的名称
        if (annotationInfo.getName() != null && !annotationInfo.getName().equals(parameter.getNameAsString())) {
            paramInfo.setParameterName(annotationInfo.getName());
        }
    }

    /**
     * 获取简单类型名称
     */
    private String getSimpleTypeName(String fullTypeName) {
        // 处理泛型
        if (fullTypeName.contains("<")) {
            fullTypeName = fullTypeName.substring(0, fullTypeName.indexOf("<"));
        }

        // 获取简单类名
        int lastDot = fullTypeName.lastIndexOf('.');
        return lastDot >= 0 ? fullTypeName.substring(lastDot + 1) : fullTypeName;
    }
}